#include "workthread.h"

#include <QDir>
#include <QDebug>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QByteArray>
#include <QDirIterator>

#include "global.h"

WorkThread::WorkThread()
{
    m_isComplete = true;
}

void WorkThread::createWorkDir()
{
    emit signalWorkProgress("开始创建工作目录");

    Global::g_packageInfo->m_workdir = Global::g_packageInfo->m_workdir + "/" + Global::g_packageInfo->m_softName;

    QDir workDir;
    if (!workDir.exists(Global::g_packageInfo->m_workdir))
    {
        workDir.mkdir(Global::g_packageInfo->m_workdir);
    }

    emit signalWorkProgress("创建工作目录完成");
}

void WorkThread::saveConfigToJson()
{
    QFile configFile(Global::g_packageInfo->m_workdir + "/config.json");
    if (!configFile.open(QIODevice::ReadWrite))
    {
        qDebug() << "File open error!";
        return;
    }

    QJsonObject configObject;
    configObject.insert("mainterName", Global::g_packageInfo->m_mainterName);
    configObject.insert("mainterEmail", Global::g_packageInfo->m_mainterEmail);
    configObject.insert("packageName", Global::g_packageInfo->m_packageName);
    configObject.insert("softName", Global::g_packageInfo->m_softName);
    configObject.insert("softVersion", Global::g_packageInfo->m_softVersion);
    configObject.insert("softArch", Global::g_packageInfo->m_softArch);
    configObject.insert("softHomepage", Global::g_packageInfo->m_softHomepage);
    configObject.insert("softDescribe", Global::g_packageInfo->m_softDescribe);
    configObject.insert("softDepends", Global::g_packageInfo->m_softDepends);
    configObject.insert("desktopExec", Global::g_packageInfo->m_desktopExec);
    configObject.insert("desktopIcon", Global::g_packageInfo->m_desktopIcon);
    configObject.insert("desktopCategory", Global::g_packageInfo->m_desktopCategory);
    configObject.insert("desktopName", Global::g_packageInfo->m_desktopName);
    configObject.insert("softDir", Global::g_packageInfo->m_softDir);

    QJsonDocument jsonDoc;
    jsonDoc.setObject(configObject);

    configFile.write(jsonDoc.toJson());
    configFile.close();
}

void WorkThread::createDebDir()
{
    emit signalWorkProgress("开始创建打包目录");
    QDir workDir;
    QString debDir = QString("%1/%2").arg(Global::g_packageInfo->m_workdir, Global::g_packageInfo->m_softArch);
    if (!workDir.exists(debDir))
    {
        workDir.mkdir(debDir);
    }else {
        workDir.setPath(debDir);
        workDir.removeRecursively();
        workDir.mkdir(debDir);
    }

    Global::g_packageInfo->m_debDebianPath = QString("%1/%2/DEBIAN").arg(Global::g_packageInfo->m_workdir, Global::g_packageInfo->m_softArch);
    Global::g_packageInfo->m_debFilePath = QString("%1/%2/opt/apps/%3/files").arg(Global::g_packageInfo->m_workdir, Global::g_packageInfo->m_softArch, Global::g_packageInfo->m_packageName);
    Global::g_packageInfo->m_debApplicationPath = QString("%1/%2/opt/apps/%3/entries/applications").arg(Global::g_packageInfo->m_workdir, Global::g_packageInfo->m_softArch, Global::g_packageInfo->m_packageName);
    Global::g_packageInfo->m_debIconPath = QString("%1/%2/opt/apps/%3/entries/icons").arg(Global::g_packageInfo->m_workdir, Global::g_packageInfo->m_softArch, Global::g_packageInfo->m_packageName);

    workDir.mkpath(Global::g_packageInfo->m_debDebianPath);
    workDir.mkpath(Global::g_packageInfo->m_debFilePath);
    workDir.mkpath(Global::g_packageInfo->m_debApplicationPath);
    workDir.mkpath(Global::g_packageInfo->m_debIconPath);
    emit signalWorkProgress("创建打包目录完成");
}

void WorkThread::createControlFile()
{
    emit signalWorkProgress("开始创建control文件");
    QString path = QString("%1/control").arg(Global::g_packageInfo->m_debDebianPath);
    QFile controlFile(path);
    if (!controlFile.open(QIODevice::ReadWrite | QIODevice::Text))
    {
        qDebug() << "111File open error!" << controlFile.errorString();
        return;
    }

    QString mainter = QString("%1 <%2>").arg(Global::g_packageInfo->m_mainterName, Global::g_packageInfo->m_mainterEmail);

    QString control;
    if (Global::g_packageInfo->m_softDepends.isEmpty())
    {
        control = QString("Package: %1\n"
                                  "Version: %2\n"
                                  "Architecture: %3\n"
                                  "Homepage: %4\n"
                                  "Maintainer: %5\n"
                                  "Description: 由upTool工具构建\n"
                                  " %6").arg(Global::g_packageInfo->m_packageName, Global::g_packageInfo->m_softVersion,
                                                             Global::g_packageInfo->m_softArch, Global::g_packageInfo->m_softHomepage, mainter,
                                             Global::g_packageInfo->m_softDescribe);
    }else {

        control = QString("Package: %1\n"
                                  "Version: %2\n"
                                  "Architecture: %3\n"
                                  "Homepage: %4\n"
                                  "Maintainer: %5\n"
                                  "Depends: %6\n"
                                  "Description: 由upTool工具构建\n"
                                  " %7").arg(Global::g_packageInfo->m_packageName, Global::g_packageInfo->m_softVersion,
                                                             Global::g_packageInfo->m_softArch, Global::g_packageInfo->m_softHomepage, mainter,
                                             Global::g_packageInfo->m_softDepends, Global::g_packageInfo->m_softDescribe);
    }

    controlFile.write(QString(control+"\n").toUtf8());
    controlFile.close();
    emit signalWorkProgress("control文件创建完成");
}

void WorkThread::createDesktopFile()
{
    emit signalWorkProgress("开始创建desktop文件");
    QString path = QString("%1/%3.desktop").arg(Global::g_packageInfo->m_debApplicationPath, Global::g_packageInfo->m_packageName);
    QFile desktopFile(path);
    if (!desktopFile.open(QIODevice::ReadWrite))
    {
        qDebug() << "File open error!";
        return;
    }

    QString execPath = QString("/opt/apps/%1/files").arg(Global::g_packageInfo->m_packageName);
    Global::g_packageInfo->m_desktopExec = execPath + Global::g_packageInfo->m_desktopExec.remove(Global::g_packageInfo->m_softDir);

    QFileInfo fileInfo(Global::g_packageInfo->m_desktopIcon);
    QString cmd = QString("cp %1 %2").arg(Global::g_packageInfo->m_desktopIcon, Global::g_packageInfo->m_debIconPath);
    qDebug() << cmd;
    system(cmd.toUtf8());
    Global::g_packageInfo->m_desktopIcon = QString("/opt/apps/%1/entries/icons/%2").arg(Global::g_packageInfo->m_packageName, fileInfo.fileName());

    QString desktop = QString("[Desktop Entry]\n"
                              "Type=Application\n"
                              "Exec=%1\n"
                              "Icon=%2\n"
                              "Name=%3\n"
                              "Comment=%3\n"
                              "Categories=%4").arg(Global::g_packageInfo->m_desktopExec, Global::g_packageInfo->m_desktopIcon,
                                                   Global::g_packageInfo->m_desktopName, Global::g_packageInfo->m_desktopCategory);
    desktopFile.write(QString(desktop+"\n").toUtf8());
    desktopFile.close();

    emit signalWorkProgress("desktop文件创建完成");
}

void WorkThread::createInfoFile()
{
    emit signalWorkProgress("开始创建info文件");

    QString path = QString("%1/%2/opt/apps/%3/info").arg(Global::g_packageInfo->m_workdir, Global::g_packageInfo->m_softArch, Global::g_packageInfo->m_packageName);
    QFile infoFile(path);
    if (!infoFile.open(QIODevice::ReadWrite))
    {
        qDebug() << "File open error!";
        return;
    }


    QJsonArray archArray;
    archArray.append(Global::g_packageInfo->m_softArch);

    QJsonObject permissionsObject;
    permissionsObject.insert("autostart", "false");
    permissionsObject.insert("notification", "false");
    permissionsObject.insert("trayicon", "false");
    permissionsObject.insert("clipboard", "false");
    permissionsObject.insert("account", "false");
    permissionsObject.insert("bluetooth", "false");
    permissionsObject.insert("camera", "false");
    permissionsObject.insert("audio_record", "false");
    permissionsObject.insert("installed_apps", "false");

    QJsonObject infoObject;
    infoObject.insert("appid", QString("%1").arg(Global::g_packageInfo->m_packageName));
    infoObject.insert("name", QString("%1").arg(Global::g_packageInfo->m_softName));
    infoObject.insert("version", QString("%1").arg(Global::g_packageInfo->m_softVersion));
    infoObject.insert("arch", archArray);
    infoObject.insert("permissions", permissionsObject);

    QJsonDocument jsonDoc;
    jsonDoc.setObject(infoObject);

    infoFile.open(QIODevice::ReadWrite|QIODevice::Text);
    QString control = QString();
    infoFile.write(jsonDoc.toJson());
    infoFile.close();

    emit signalWorkProgress("info文件创建完成");
}

void WorkThread::moveSrcFile()
{
    emit signalWorkProgress("开始拷贝程序文件");

    QDir srcDir;
    if (!srcDir.exists(Global::g_packageInfo->m_softDir))
    {
        qDebug() << "deb目录不存在";
        return ;
    }

    QString path = QString("%1/%2/opt/apps/%3/files").arg(Global::g_packageInfo->m_workdir, Global::g_packageInfo->m_softArch, Global::g_packageInfo->m_packageName);
    QString cmd = QString("cp -r %1/* %2").arg(Global::g_packageInfo->m_softDir, path);
    qDebug() << cmd;
    system(cmd.toUtf8());

    emit signalWorkProgress("程序文件拷贝完成");
}

void WorkThread::makeDebPackage()
{
    emit signalWorkProgress("开始打包");

    checkSandboxFile();
    QString debDir = QString("%1/%2").arg(Global::g_packageInfo->m_workdir, Global::g_packageInfo->m_softArch);
    m_process = new QProcess();
    connect(m_process,SIGNAL(readyReadStandardOutput()),this,SLOT(readyReadStandardOutput()));
    connect(m_process,SIGNAL(readyReadStandardError()),this,SLOT(readyReadStandardError()));
    connect(m_process,SIGNAL(finished(int)),SLOT(finished()));

    m_process->start("dpkg-deb", {"-b" , debDir , Global::g_packageInfo->m_workdir});
    m_process->waitForStarted();

    m_process->waitForFinished(-1);

    sleep(2);
}

void WorkThread::checkSandboxFile()
{

    QDir dir(Global::g_packageInfo->m_debFilePath);
    if (!dir.exists())
    {
        return;
    }

    QStringList filters;
    filters << QString("chrome-sandbox");

    QDirIterator dirIterator(Global::g_packageInfo->m_debFilePath, {"chrome-sandbox"},
                             QDir::Files | QDir::NoSymLinks,
                             QDirIterator::Subdirectories);

    while (dirIterator.hasNext())
    {
        emit signalWorkProgress("检测到chrome-sandbox,添加root和4755权限");
        dirIterator.next();
        QFileInfo fileInfo = dirIterator.fileInfo();
        QString filePath = fileInfo.absoluteFilePath();
        QString cmd = QString("pkexec chown root:root %1").arg(filePath);
        system(cmd.toUtf8());
        cmd = QString("pkexec chmod 4755 %1").arg(filePath);
                system(cmd.toUtf8());
    }
}

void WorkThread::startWork()
{
    createWorkDir();
    saveConfigToJson();
    createDebDir();
    createControlFile();
    createDesktopFile();
    createInfoFile();
    moveSrcFile();
    makeDebPackage();
}

void WorkThread::run()
{
    startWork();
}

void WorkThread::readyReadStandardOutput()
{
 //   emit signalWorkProgress(m_process->readAllStandardOutput());
    QString str = m_process->readAllStandardOutput().replace("\n","");
    if (!str.isEmpty())
    {
        m_isComplete = true;
        emit signalWorkProgress(str);
    }
}

void WorkThread::readyReadStandardError()
{
  //  emit signalWorkProgress(m_process->readAllStandardError());
    QString str = m_process->readAllStandardError().replace("\n","");
    if (!str.isEmpty())
    {
        m_isComplete = false;
        emit signalWorkProgress(str);
    }
}

void WorkThread::finished()
{
    if (m_isComplete)
    {
        emit signalWorkProgress("打包完成");
    }else {
        emit signalWorkProgress("打包失败");
    }
}
